package com.qf.fmall.user.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.fmall.user.entity.User;
import com.qf.fmall.user.mapper.UserDao;
import com.qf.fmall.user.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmall.utils.TokenUtils;
import com.qf.fmall.vo.ResultVo;
import com.qf.fmall.vo.UserRegistVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dongjunlong
 * @since 2024-01-15
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements IUserService {

    @Autowired
    private UserDao userDao;

    @Override
    public boolean regist(UserRegistVo userRegistVo) {

        //1. 校验两次密码是否一致
        String password = userRegistVo.getPassword();
        String repassword = userRegistVo.getRepassword();
        if (!password.equals(repassword)){
            log.info("两次密码不一致，注册失败");
            return false;
        }

        //2. 校验用户名是否已经存在
        String username = userRegistVo.getUsername();
        User dbuser = userDao.selectOne(new QueryWrapper<User>().eq("username", username));
        if (dbuser!=null){
            log.info("用户名已存在");
            return false;
        }

        //3. 进行用户数据的写入
        User user = new User();
        user.setUsername(username);
        // 处理用户的密码
        String salt =  createSalt(8);  // 生成随机字符串，作为密码的盐
        String dbpassword =  createPassword(password,salt);  // 产生密码
        user.setPassword(dbpassword);  // 设置密码到user对象，准备写入数据库
        user.setUserRegtime(new Date());
        user.setUserModtime(new Date());
        user.setUserImg("1.webp");
        user.setSalt(salt);

        userDao.insert(user);
        log.info("用户注册成功!");
        return true;
    }

    @Override
    public ResultVo login(String username, String password) {

        //1. 根据username查询用户信息
        User dbuser = userDao.selectOne(new QueryWrapper<User>().eq("username", username));
        if (dbuser==null){
            log.info("用户名没有对应的用户信息");
            return new ResultVo(-1, "用户名没有对应的用户信息", null);
        }

        //2. 比对密码是否正确
        String salt = dbuser.getSalt();
        String dbpassword = dbuser.getPassword();
        // 重新计算密码的MD5值
        String s = DigestUtil.md5Hex(password + salt);
        if (!dbpassword.equals(s)){
            log.info("密码错误");
            return new ResultVo(-1, "密码错误", null);
        }

        //3. 签发 token
        String token = TokenUtils.createToken(username, 120);

        dbuser.setPassword(null);
        dbuser.setSalt(null);
        return new ResultVo(10000, token, dbuser);

    }

    /**
     * 根据用户的原始密码和盐创建加密的密码
     * @param password
     * @param salt
     * @return
     */
    private String createPassword(String password, String salt) {

        //1. MD5 实现密码加密
        String md5password = DigestUtil.md5Hex(password + salt);

        return md5password;
    }

    /**
     * 产生长度为i的随机字符串
     * @param i 注意，i的长度不要大于32
     * @return
     */
    private String createSalt(int i) {

        if (i>32){
            throw new RuntimeException("盐的长度不能大于32位字符串");
        }

        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        return uuid.substring(0, i);

    }
}
